<template>
    <div class="xpage">
      <div class="left_obj">
        <div 
          v-for="item in deviceList" 
          :key="item.label"
          draggable="true"
          @dragstart="handleDragStart($event, item)"
          class="draggable-item"
        >
          {{ item.label }}
        </div>
      </div>
  
      <div 
        ref="container" 
        id="container" 
        class="my_container"
        @dragover="handleDragOver"
        @drop="handleDrop"
      ></div>
  
      <!-- 参数编辑模态框 -->
      <a-modal
        v-model:visible="modalVisible"
        :title="`编辑设备 - ${selectedDevice?.data?.label || ''}`"
        @ok="handleModalOk"
        @cancel="handleModalCancel"
      >
        <a-form :model="deviceForm" layout="vertical">
          <a-form-item 
            v-for="param in deviceParams" 
            :key="param.key"
            :label="param.label"
          >
            <a-input 
              v-model:value="deviceForm[param.key]" 
              :suffix="param.unit || ''"
            />
          </a-form-item>
        </a-form>
      </a-modal>
    </div>
  </template>
  
  <script setup>
  import { ref, reactive,onMounted } from 'vue';
  import { Graph } from '@antv/x6';
  import { Modal as AModal, Form as AForm, FormItem as AFormItem, Input as AInput } from 'ant-design-vue';
  
  const container = ref(null);
  const graph = ref(null);
  const draggedItem = ref(null);
  const modalVisible = ref(false);
  const selectedDevice = ref(null);
  
  // 设备参数配置
  const deviceParamsConfig = {
    meter: [
      { key: 'power', label: '功率', unit: 'kW', defaultValue: '10' },
      { key: 'voltage', label: '电压', unit: 'V', defaultValue: '220' }
    ],
    pcs: [
      { key: 'capacity', label: '容量', unit: 'kWh', defaultValue: '50' },
      { key: 'efficiency', label: '效率', unit: '%', defaultValue: '95' }
    ],
    bms: [
      { key: 'cells', label: '电池数量', unit: '节', defaultValue: '16' },
      { key: 'temperature', label: '温度', unit: '°C', defaultValue: '25' }
    ]
  };
  
  // 设备列表
  const deviceList = [
    { label: 'PCS', type: 'pcs' },
    { label: 'BMS', type: 'bms' },
    { label: '电表1', type: 'meter' }
  ];
  
  // 表单数据
  const deviceForm = reactive({});
  const deviceParams = ref([]);
  
  // 端口配置
  const ports = {
    groups: {
      top: { position: 'top', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
      right: { position: 'right', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
      bottom: { position: 'bottom', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
      left: { position: 'left', attrs: { circle: { r: 4, magnet: true, stroke: '#5F95FF', strokeWidth: 1, fill: '#fff', style: { visibility: 'hidden' } } } },
    },
    items: [
      { group: 'top' },
      { group: 'right' },
      { group: 'bottom' },
      { group: 'left' },
    ],
  };
  
  // 注册自定义节点
  Graph.registerNode('device-node', {
    inherit: 'rect',
    markup: [
      { tagName: 'rect', selector: 'body' },
      { tagName: 'image', selector: 'image' },
      { tagName: 'text', selector: 'text' },
      { tagName: 'text', selector: 'params' }
    ],
    attrs: {
      body: { 
        stroke: '#5F95FF', 
        strokeWidth: 1, 
        fill: '#EFF4FF',
        rx: 6,
        ry: 6
      },
      image: { 
        'xlink:href': 'https://gw.alipayobjects.com/zos/bmw-prod/c55d7ae1-8d20-4585-bd8f-ca23653a4489.svg',
        width: 40,
        height: 40,
        x: 10,
        y: 10
      },
      text: { 
        text: '设备',
        fontSize: 12,
        fill: '#262626',
        refX: 0.5,
        refY: '100%',
        y: -10,
        textAnchor: 'middle'
      },
      params: {
        text: '',
        fontSize: 10,
        fill: '#666',
        refX: 0.5,
        refY: '100%',
        y: 5,
        textAnchor: 'middle'
      }
    },
    ports: { ...ports },
  }, true);
  
  // 创建设备节点
  const createDeviceNode = (graph, item, position) => {
    // 初始化设备参数
    const params = {};
    const paramsConfig = deviceParamsConfig[item.type] || [];
    paramsConfig.forEach(param => {
      params[param.key] = param.defaultValue;
    });
  
    return graph.createNode({
      shape: 'device-node',
      width: 120,
      height: 100,
      x: position.x,
      y: position.y,
      attrs: {
        text: { text: item.label },
        params: { 
          text: paramsConfig.map(p => `${p.label}: ${params[p.key]}${p.unit}`).join('\n')
        }
      },
      data: {
        type: item.type,
        label: item.label,
        params: params
      }
    });
  };
  
  // 更新节点显示参数
  const updateNodeParamsDisplay = (node) => {
    const paramsConfig = deviceParamsConfig[node.data.type] || [];
    node.attr('params/text', paramsConfig.map(p => `${p.label}: ${node.data.params[p.key]}${p.unit}`).join('\n'))
  }
  
  // 拖拽开始
  const handleDragStart = (e, item) => {
    draggedItem.value = item;
    e.dataTransfer.setData('text/plain', item.label);
    e.dataTransfer.effectAllowed = 'copy';
  };
  
  // 拖拽经过画布
  const handleDragOver = (e) => {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
  };
  
  // 拖拽放置
  const handleDrop = (e) => {
    e.preventDefault();
    if (!draggedItem.value || !graph.value) return;
    
    const rect = container.value.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;
    
    const node = createDeviceNode(graph.value, draggedItem.value, { x, y });
    graph.value.addNode(node);
    
    draggedItem.value = null;
  };
  
  // 显示编辑模态框
  const showEditModal = (node) => {
    selectedDevice.value = node;
    deviceParams.value = deviceParamsConfig[node.data.type] || [];
    
    // 初始化表单数据
    Object.keys(deviceForm).forEach(key => delete deviceForm[key]);
    deviceParams.value.forEach(param => {
      deviceForm[param.key] = node.data.params[param.key];
    });
    
    modalVisible.value = true;
  };
  
  // 模态框确定
  const handleModalOk = () => {
    // 更新设备参数
    deviceParams.value.forEach(param => {
      selectedDevice.value.data.params[param.key] = deviceForm[param.key];
    });
    
    // 更新节点显示
    updateNodeParamsDisplay(selectedDevice.value);
    modalVisible.value = false;
  };
  
  // 模态框取消
  const handleModalCancel = () => {
    modalVisible.value = false;
  };
  
  onMounted(() => {
    // 初始化画布
    graph.value = new Graph({
      panning: { enabled: true, modifiers: 'space', eventTypes: "leftMouseDown" },
      scaling: { min: 0.05, max: 1 },
      mousewheel: { 
        enabled: true, 
        modifiers: ['ctrl', 'meta'],
        guard: (e) => !e.altKey
      },
      grid: { 
        size: 10,
        visible: true,
        args: { color: '#a0a0a0', thickness: 1 }
      },
      container: container.value,
      connecting: { anchor: 'orth' },
    });
  
    // 添加节点点击事件
    graph.value.on('node:click', ({ node }) => {
      showEditModal(node);
    });
  
    // 添加一个示例节点
    const sampleNode = createDeviceNode(graph.value, 
      { label: '示例电表', type: 'meter' }, 
      { x: 100, y: 100 }
    );
    graph.value.addNode(sampleNode);
  });
  </script>
  
  <style scoped>
  .xpage {
    height: 100vh;
    display: flex;
  }
  
  .my_container {
    flex: 1;
    height: 100%;
    border: 1px solid #d9d9d9;
    background: #f5f5f5;
  }
  
  .left_obj {
    background-color: #fff;
    width: 200px;
    padding: 10px;
    border-right: 1px solid #d9d9d9;
  }
  
  .draggable-item {
    background-color: #1890ff;
    color: white;
    text-align: center;
    line-height: 40px;
    border-radius: 4px;
    cursor: move;
    margin-bottom: 10px;
    user-select: none;
    transition: all 0.3s;
  }
  
  .draggable-item:hover {
    background-color: #40a9ff;
    transform: translateX(5px);
  }
  </style>